﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DealDataByFFT
{
    public partial class Form1 : Form
    {
        public static string file = "";
        FFT wavFFT = new FFT();
        public static Queue<float[]> FFTQueue = new Queue<float[]>();
        public Queue<float[]> frequency1 = new Queue<float[]>();
        float y1_max = 0;
        int num = 1000;
        public List<float> x = new List<float>();
        public Form1()
        {
            InitializeComponent();
            button2.Enabled = false;
            double interval = 0.5;
            double n = 0;
            for (int i = 0; i < num; i++)
            {
                n = n + interval;
                x.Add((float)n);
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //初始化变量
            FFTQueue.Clear();
            frequency1.Clear();
            y1_max = 0;
            Droplet.DropFFT.isFirst = true;
            if(Droplet.DropFFT.amp_ca_queue != null)
                Droplet.DropFFT.amp_ca_queue.Clear();
            if (Droplet.DropFFT.diff_arr_queue != null)
                Droplet.DropFFT.diff_arr_queue.Clear();
            //初始化变量完成
            OpenFileDialog dialog = new OpenFileDialog();
            dialog.Multiselect = false;//该值确定是否可以选择多个文件
            dialog.Title = "请选择文件夹";
            dialog.Filter = "所有文件(*.*)|*.*";
            if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                file = dialog.FileName;
            }
            button1.Enabled = false;
            button2.Enabled = true;
            label1.Text = file;
            Console.WriteLine(file);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (file != "")
            {
                button2.Enabled = false;
                string timeNow = DateTime.Now.ToString("yyyy年MM月dd日HH时mm分ss秒");
                FileStream fs = new FileStream(file, FileMode.Open);
                int fsLen = (int)fs.Length;
                byte[] heByte = new byte[fsLen];
                int r = fs.Read(heByte, 0, heByte.Length);
                byte[] Signalbyte_ori = new byte[2048*2];
                byte[] Signalbyte = new byte[2048*2];
                int[] SingalUint = new int[1];//GuiyiWave方法会重新分配空间
                //存储频率值文件打开
                string file_fre = @".\FreqData\" + timeNow + ".txt";
                FileStream fs_n = new FileStream(file_fre, FileMode.Create);//新建文件
                StreamWriter sw_n = new StreamWriter(fs_n, System.Text.Encoding.Default);
                //存储频率值文件打开结束

                for (int i = 0; i < fsLen/(2048*2); i++)
                {
                    Array.Copy(heByte,i*2048*2, Signalbyte_ori, 0,2048*2);
                    short[] SignalUnit = new short[1];
                    SignalUnit = Droplet.DropFFT.buffer2Arr(Signalbyte_ori);
                    short readData_from_ori = SignalUnit[SignalUnit.Length - 1];
                    short readflag_from_ori = SignalUnit[SignalUnit.Length - 2];
                    double readFre_from_ori = new double();
                    if (readflag_from_ori == 0)
                    {
                        readFre_from_ori = readData_from_ori;
                    }
                    else if(readflag_from_ori == 1)
                    {
                        readFre_from_ori = readData_from_ori + 0.5;
                    }
                    else if(readflag_from_ori == 2)
                    {
                        readFre_from_ori = readData_from_ori - 0.5;
                    }
                    else
                    {
                        //若标志位不上上面几个数，则证明不存在标准频率。则将其赋值为0
                        readFre_from_ori = 0;
                    }
                    
                    Signalbyte = Droplet.DropFFT.VoiceYuanSheng(Signalbyte_ori, 1);
                    Droplet.DropFFT.GuiyiWave(ref SingalUint, Signalbyte);
                    float[] samples = new float[SingalUint.Length];
                    Array.Copy(SingalUint, samples, SingalUint.Length);
                    wavFFT.calculate(ref samples);
                    wavFFT.covertDB(ref samples);
                    samples[15] = (float)(samples[15] * 0.7);
                    float[] temp_samples = new float[samples.Length];
                    float[] temp_temp_samples = new float[samples.Length];
                    //Array.Copy(samples, temp_samples, samples.Length);
                    float[] freAmp = new float[2];
                    Queue<float[]> bigAmp = new Queue<float[]>();
                    float[][] bigAmpData = new float[5][];
                    float[] popData = new float[3];
                    //五秒的FFT累加
                    if (FFTQueue.Count >= 5)
                    {
                        FFTQueue.Dequeue();
                        FFTQueue.Enqueue(samples);
                    }
                    else
                    {
                        FFTQueue.Enqueue(samples);
                    }
                    //Console.WriteLine(FFTQueue.Count);
                    for (int o = 0; o < samples.Length; o++)
                    {
                        float now = new float();
                        for (int q = 0; q < FFTQueue.Count; q++)
                        {
                            now = now + FFTQueue.ElementAt(q)[o];
                        }
                        temp_samples[o] = now / FFTQueue.Count;
                    }
                    Array.Copy(temp_samples, temp_temp_samples, temp_samples.Length);

                    //兼容解决谐波问题，取能量最大的五个，然后用最大的分别处以第2二到第4的，找到能整除的最小频率作为本次的频率
                    for (int j = 0; j < 5; j++)
                    {
                        bigAmpData[j] = new float[3];
                        for (int ii = 0; ii < 1000; ii++)//只显示需要的频率范围
                        {
                            if (y1_max < temp_temp_samples[ii])
                            {
                                y1_max = temp_temp_samples[ii];
                                bigAmpData[j][0] = ii;
                                bigAmpData[j][1] = x[ii];
                                bigAmpData[j][2] = y1_max;
                            }
                        }
                        bigAmp.Enqueue(bigAmpData[j]);
                        y1_max = 0;
                        temp_temp_samples[(int)bigAmpData[j][0]] = 0;
                    }
                    //首先设置本次频率和强度就是最大强度对应的频率
                    freAmp[0] = bigAmp.ElementAt(0)[1];
                    freAmp[1] = bigAmp.ElementAt(0)[2];

                    //加入频率校正,哪个对应标准频率的差值最小，则确定频率
                    //谐波问题解决
                    for (int ii = bigAmp.Count - 1; ii >= 0; ii--)
                    {
                        popData = bigAmp.ElementAt(ii);
                        if ((bigAmp.ElementAt(0)[1] < num / 2) && (bigAmp.ElementAt(0)[1] % popData[1] == 0) && (popData[1] < freAmp[0]) && (popData[0] != 0) && (popData[2] > freAmp[1] * 0.7))
                        {
                            freAmp[0] = popData[1];
                            freAmp[1] = popData[2];
                        }
                    }
                    bigAmp.Clear();//清空队列
                    y1_max = 0;

                    float[] data_ca = new float[2];
                    if (readFre_from_ori != 0)
                    {//如果有标准频率校正，则不做纵向统计计算
                        data_ca[0] = (float)readFre_from_ori;
                    }
                    else
                    {
                        if (frequency1.Count == 5)
                        {
                            frequency1.Dequeue();//弹出第一个
                            frequency1.Enqueue(freAmp);//在末尾添加新的数据
                        }
                        else
                        {
                            frequency1.Enqueue(freAmp);//在末尾添加新的数据
                        }

                        data_ca = Droplet.DropFFT.Max_probability(frequency1);
                    }
                    sw_n.Write(data_ca[0]);
                    sw_n.Write("\r\n");
                    sw_n.Flush();
                }
                fs.Close();
                sw_n.Close();

                Form2 frm = new Form2(file_fre);//首先实例化
                frm.ShowDialog();//Show方法
                button1.Enabled = true;
                
            }
        }
    }
}
